﻿''' <summary>
''' 
''' </summary>
''' <remarks></remarks>
''' <features></features>
''' <stepthrough></stepthrough>
Public Class FileFolder


#Region "       Properties      >>>"

    Dim _Path As String
    ''' <summary>The Current Path\Location of the File\Folder</summary> 
    Public ReadOnly Property Path As String
        Get
            Return _Path
        End Get
    End Property


    ''' <summary>
    ''' Creates a New <see cref="CShItem"/> and Returns it 
    ''' </summary>
    ''' <value>Returns A New CShItem(Path)</value>
    ''' <remarks>
    ''' <para>
    ''' This only Creates and Returns the New CShItem(Path) so there is No Wasted Resources
    ''' Code: <code>Return New CShItem(Path)</code>
    ''' </para>
    ''' </remarks>
    Public ReadOnly Property _Special As CShItem
        Get
            Return New CShItem(Path)
        End Get
    End Property


    ''' <summary>
    ''' The FolderFolder(Its A Folder) that Contains the Current File\Folder
    ''' </summary>
    ''' <remarks>Code: <code>Return New FileFolder(Me.Path.Remove(Me.Path.Length - (Me.Path.Split("\").Last.Count + 1)))</code></remarks>
    Public ReadOnly Property Parent As FileFolder
        Get
            Return New FileFolder(Me.Path.Remove(Me.Path.Length - (Me.Path.Split("\").Last.Count + 1)))
        End Get
    End Property


    ''' <summary>
    ''' Returns A New Helper Which Encapsulates most of the Functionality of this Class
    ''' </summary>
    ''' <remarks></remarks>
    Public ReadOnly Property Actions As Helper
        Get
            Return New Helper(Me)
        End Get
    End Property


    Public ReadOnly Property IsFile As Boolean
        Get
            Return Path.Contains(".")
        End Get
    End Property


    ''' <summary>
    ''' The Name of the FileFolder
    ''' </summary>
    ''' <remarks>Code: <code>Return If(IsFile, IO.Path.GetFileName(Me.Path), IO.Path.GetDirectoryName(Path))</code></remarks>
    Public ReadOnly Property Name As String
        Get
            Return If(IsFile, IO.Path.GetFileName(Me.Path), IO.Path.GetDirectoryName(Path))
        End Get
    End Property


    ''' <summary>
    ''' Tells if the File\Folder Exists
    ''' </summary>
    ''' <remarks>Code <code> Return If(IsFile, My.Computer.FileSystem.FileExists(Me.Path), My.Computer.FileSystem.DirectoryExists(Me.Path))</code></remarks>
    Public ReadOnly Property Exists As Boolean
        Get
            Return If(IsFile, My.Computer.FileSystem.FileExists(Me.Path), My.Computer.FileSystem.DirectoryExists(Me.Path))
        End Get
    End Property

#End Region


#Region "       Shared          >>>"

    ''' <summary>
    ''' Returns A New <see cref="FileFolder">FileFolder</see>
    ''' </summary>
    ''' <param name="Path">The Path of the File\Folder</param>
    ''' <remarks>Code: <code>Return New FileFolder(Path)</code></remarks>
    ''' <stepthrough>Enabled</stepthrough>
    <DebuggerStepThrough()>
    Public Shared Function [New](ByVal Path As String) As FileFolder
        Return New FileFolder(Path)
    End Function


    ''' <summary>
    ''' Tells Whether or not the Path is 
    ''' </summary>
    ''' <param name="Path"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    ''' <stepthrough></stepthrough>
    <Obsolete("Do not use this one", True)>
    Public Shared Function IsPathValid(ByVal Path As String) As Boolean
        Dim File As New FileFolder(Path)
        If File.Path.Contains(IO.Path.GetInvalidPathChars) Then
            Return False
        ElseIf File.IsFile AndAlso File.Path.Contains(IO.Path.GetInvalidFileNameChars) Then
            Return False
        Else
            Return True
        End If
    End Function


    ''' <summary>
    ''' Tells Whether or not the Path is for Either A File or A Folder [Depending on <paramref name="IsFile">IsFile</paramref>]
    ''' </summary>
    ''' <param name="Path">The Path of the File/Folder</param>
    ''' <param name="IsFile">States FOR SURE whether or not the Path is for A File(True) Or Folder(False)</param>
    ''' <returns>Returns True If the Path is Valid</returns>
    ''' <remarks></remarks>
    ''' <stepthrough></stepthrough>

    Public Shared Function IsPathValid(ByVal Path As String, ByVal IsFile As Boolean) As Boolean
        If Path.Contains(IO.Path.GetInvalidPathChars) Then
            Return False
        ElseIf IsFile = True AndAlso Path.Contains(IO.Path.GetInvalidFileNameChars) Then
            Return False
        Else
            Return True
        End If
    End Function


    ''' <summary>
    ''' If the File\Folder does not Exist then it is Created
    ''' </summary>
    ''' <returns><c>If</c> Created Then Returns True <c>Else</c> False</returns>
    ''' <remarks></remarks>
    ''' <stepthrough>Enabled</stepthrough>
    <DebuggerStepThrough()>
    Public Shared Function TryCreate(ByVal Path As String) As Boolean
        Return New FileFolder(Path).TryCreate
    End Function

#End Region


    ''' <summary>
    ''' Creates A New FileFolder Object
    ''' </summary>
    ''' <param name="Path">The Path of the File\Folder</param>
    ''' <remarks></remarks>
    ''' <stepthrough>Enabled</stepthrough>
    <DebuggerStepThrough()>
    Sub New(ByVal Path As String)
        Me._Path = Path
    End Sub


    ''' <summary>
    ''' If the File\Folder does not Exist then it is Created
    ''' </summary>
    ''' <returns><c>If</c> Created Then Returns True <c>Else</c> False</returns>
    ''' <remarks></remarks>
    ''' <stepthrough>Enabled</stepthrough>
    <DebuggerStepThrough()>
    Public Function TryCreate() As Boolean
        If Me.Exists = True Then
            Return False
        ElseIf Me.IsFile = True Then
            IO.File.Create(Me.Path).Close()
        Else
            My.Computer.FileSystem.CreateDirectory(Me.Path)
            'IO.Directory.CreateDirectory(Me.Path)
        End If
        Return True
    End Function


    ''' <summary>
    ''' Creates the File\Folder
    ''' </summary>
    ''' <remarks>Code: <code>If Me.IsFile = True Then IO.File.Create(Me.Path) Else IO.Directory.CreateDirectory(Me.Path)</code></remarks>
    ''' <stepthrough>Enabled</stepthrough>
    <DebuggerStepThrough()>
    Public Sub Create()
        If Me.IsFile = True Then IO.File.Create(Me.Path).Close() Else My.Computer.FileSystem.CreateDirectory(Me.Path) 'IO.Directory.CreateDirectory(Me.Path)
    End Sub


End Class




Partial Class FileFolder
    Public NotInheritable Class Helper
        Dim Parent As FileFolder

        Friend Sub New(ByRef Parent As FileFolder)
            Me.Parent = Parent
        End Sub


        ''' <summary>
        ''' Lets the User Select the Location to Move the File\Folder
        ''' </summary>
        ''' <remarks></remarks>
        ''' <stepthrough></stepthrough>
        Public Sub Move()
            If Me.Parent.IsFile Then
                Dim Browser As New FolderBrowserDialog With {.RootFolder = Environment.SpecialFolder.Desktop}
                Browser.Description = "Select A Location for the Folder"
                If Browser.ShowDialog = DialogResult.OK Then
                    Me.Move(Browser.SelectedPath)
                End If
            Else
                Dim Browser As New SaveFileDialog With {.InitialDirectory = Environment.SpecialFolder.Desktop}
                Browser.Title = "Select A Location for the Folder"
                If Browser.ShowDialog = DialogResult.OK Then
                    Me.Move(Browser.FileName)
                End If
            End If
        End Sub


        ''' <summary>
        ''' Move the File\Folder to the Specified Location [I think this des not show any Dialog Boxes for Errors or Progress]
        ''' </summary>
        ''' <param name="Location">The [File\Folder]'s Destination</param>
        ''' <remarks></remarks>
        ''' <stepthrough></stepthrough>
        Public Sub Move(ByVal Location As String)
            If Parent.Exists = False Then
                Throw New FileFolderException(FileFolderException.ErrorType.DoesNotExist)
            ElseIf IsPathValid(Location, False) Then
                Throw New FileFolderException(FileFolderException.ErrorType.InvalidPathChars)
            ElseIf Parent.IsFile = False Then
                My.Computer.FileSystem.MoveDirectory(Me.Parent.Path, Location)
            ElseIf IsPathValid(Location, True) Then
                Throw New FileFolderException(FileFolderException.ErrorType.InvalidFileNameChars)
            ElseIf Me.Parent.IsFile Then
                My.Computer.FileSystem.MoveFile(Me.Parent.Path, Location)
            End If
        End Sub


        'TODO Should I Add an If to Check to see if the File Exists?
        ''' <summary>
        ''' Send the File\Folder to the Recycle Bin + Shows ConfirmationBox + ProgressBox + ErrorBoxes
        ''' </summary>
        ''' <remarks>Should I Add an If to Check to see if the File Exists?</remarks>
        ''' <stepthrough>Enabled</stepthrough>
        <DebuggerStepThrough()>
        Public Sub SendToRecycleBinA()
            If Me.Parent.IsFile Then
                My.Computer.FileSystem.DeleteFile(Me.Parent.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
            Else
                My.Computer.FileSystem.DeleteDirectory(Me.Parent.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
            End If
        End Sub


        ''' <summary>
        ''' Send the File\Folder to the Recycle Bin with only ErrorBoxes
        ''' </summary>
        ''' <remarks></remarks>
        ''' <stepthrough>Enabled</stepthrough>
        <DebuggerStepThrough()>
        Public Sub SendToRecycleBinB()
            If Me.Parent.IsFile Then
                My.Computer.FileSystem.DeleteFile(Me.Parent.Path, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin)
            Else
                My.Computer.FileSystem.DeleteDirectory(Me.Parent.Path, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin)
            End If
        End Sub


        ''' <summary>
        ''' Send the File\Folder to the Recycle Bin with no DialogBoxes [I think there are no DialogBoxes but I'm not sure]
        ''' </summary>
        ''' <remarks></remarks>
        ''' <stepthrough>Enabled</stepthrough>
        <DebuggerStepThrough()>
        Public Sub SendToRecycleBinC()
            If Me.Parent.IsFile Then
                My.Computer.FileSystem.DeleteFile(Me.Parent.Path, Nothing, FileIO.RecycleOption.SendToRecycleBin, FileIO.UICancelOption.DoNothing)
            Else
                My.Computer.FileSystem.DeleteDirectory(Me.Parent.Path, Nothing, FileIO.RecycleOption.SendToRecycleBin, FileIO.UICancelOption.DoNothing)
            End If
        End Sub


        ''' <summary>
        ''' Deletes the File\Folder
        ''' </summary>
        ''' <remarks></remarks>
        ''' <stepthrough>Enabled</stepthrough>
        <DebuggerStepThrough()>
        Public Sub Delete()
            If Me.Parent.IsFile Then
                IO.File.Delete(Me.Parent.Path)
            Else
                IO.Directory.Delete(Me.Parent.Path)
            End If
        End Sub


        ''' <summary>
        ''' Deletes this File\Folder If it Exists. If Deleted Returns True Else Returns False
        ''' </summary>
        ''' <returns>If Deleted Returns True Else Returns False</returns>
        ''' <remarks></remarks>
        ''' <stepthrough>Enabled</stepthrough>
        <DebuggerStepThrough()>
        Public Function TryDelete() As Boolean
            If Me.Parent.Exists Then
                Me.Delete()
                Return True
            Else
                Return False
            End If
        End Function
    

    End Class


End Class


Partial Class FileFolder
    Public Class FileFolderException
        Inherits Exception
        Dim _ErrorType As ErrorType

        Public Enum ErrorType
            Other
            DoesNotExist
            InvalidPathChars
            InvalidFileNameChars
        End Enum

        Sub New(ByVal ErrorType As ErrorType)
            Me._ErrorType = ErrorType
        End Sub

        Public Overrides ReadOnly Property Message As String
            Get
                Dim Text As String = "Error: " & _ErrorType.ToString & C3
                Return Text & MyBase.Message
            End Get
        End Property

    End Class


End Class